{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d1f20875-c50d-46df-906b-49ec1d0c6002",
   "metadata": {},
   "source": [
    "## 9.5 自制数据集\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "c90a18b9-d8e8-431c-856c-35f1e4ed05e1",
   "metadata": {},
   "source": [
    "### 1.任务描述\n",
    "\n",
    "在图片目录（project09\\mnist_image_label\\mnist_train_jpg_60000）中存放60000张图片，它们都是黑底白字的灰度图，每张图有28×28个像素点，每个像素点都是0～255之间的整数，纯黑色用0表示，纯白色用255表示。\n",
    "\n",
    "标签文件为project09\\mnist_image_label\\mnist_train_jpg_60000.txt，文件的每行内容是每个图片的文件名和对应的标签，中间用空格隔开，内容如下："
   ]
  },
  {
   "cell_type": "raw",
   "id": "998613ff-960f-4109-ab1a-1d6abbb657f8",
   "metadata": {},
   "source": [
    "28755_0.jpg 0\n",
    "13360_5.jpg 5\n",
    "57662_5.jpg 5"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc9637a5-1cc6-43ad-a708-2a1a0b580cd8",
   "metadata": {},
   "source": [
    "要求：\n",
    "\n",
    "使用一个方法及已有的图片和文件，自制数据集，得到NumPy格式的样本特征x_train和样本标签y_train，并将它们保存到文件，实现对文件的读取。"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "f5b4fc39-cbcf-432a-bf1e-e75e642d4b87",
   "metadata": {},
   "source": [
    "### 2.知识准备\n",
    "\n",
    "见教程。"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "c1d0295a-4ac4-470a-8263-027a3d69ac2c",
   "metadata": {},
   "source": [
    "### 3.任务分析\n",
    "\n",
    "本任务主要完成将N张28像素×28像素的图片，转化成N个大小为28×28的二维数组，每个数组对应一个标签值（0～9）。在完成图片到数组的转化后，将这些数组通过np.save方法保存到本地。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "435c6090-cfda-4f46-a550-22a368e41e4a",
   "metadata": {},
   "source": [
    "### 4.任务实施\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "ec75eb6c-5da3-467d-a471-ca3b47242dd6",
   "metadata": {},
   "source": [
    "执行代码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "2ae9da58-e339-4d22-9f8d-ca255711d89e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "解析得到的数据：\n",
      "(500, 28, 28)\n",
      "(500,)\n",
      "(500, 28, 28)\n",
      "(500,)\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "from PIL import Image\n",
    "import numpy as np\n",
    "import os\n",
    "# 图片目录\n",
    "train_path = './mnist_image_label/train_500/'\n",
    "# 标签文件\n",
    "train_txt = './mnist_image_label/train_500.txt'\n",
    "# 特征文件保存路径\n",
    "x_train_savepath = './mnist_image_label/mnist_x_train.npy'\n",
    "# 标签文件保存路径\n",
    "y_train_savepath = './mnist_image_label/mnist_y_train.npy'\n",
    "\n",
    "# 自定义函数，参数1为图片所在的目录，参数2为标签文件\n",
    "def generateds(path, txt):\n",
    "    # 以只读形式打开TXT文件\n",
    "    f = open(txt, 'r')\n",
    "    # 读取文件中的所有行\n",
    "    contents = f.readlines()  \n",
    "    # print(contents)\n",
    "    # 关闭TXT文件\n",
    "    f.close()  \n",
    "    # 建立空列表\n",
    "    x, y_ = [], []  \n",
    "    # 逐行取出\n",
    "    for content in contents:  \n",
    "        # 以空格分开，图片路径为value[0] , 标签为value[1] , 存入列表\n",
    "        value = content.split()  \n",
    "        # print(value)\n",
    "        # 拼出图片路径和文件名\n",
    "        img_path = path + value[0]  \n",
    "        # print(img_path)\n",
    "        # 读入图片，返回图片对象\n",
    "        img = Image.open(img_path)\n",
    "        # print(img)        \n",
    "        # 图片变为8位宽的灰度图片\n",
    "        img=img.convert('L')\n",
    "        # print(img)   \n",
    "        # 将图片转为np.array格式\n",
    "        img = np.array(img) \n",
    "        # print(img.shape)\n",
    "        # 数据归一化\n",
    "        img = img / 255.  \n",
    "        # 添加到列表x\n",
    "        x.append(img)  \n",
    "        # 标签添加到列表y_\n",
    "        y_.append(value[1])  \n",
    "    # 变为np.array格式\n",
    "    x = np.array(x)  \n",
    "    # 变为np.array格式\n",
    "    y_ = np.array(y_)  \n",
    "    # 变为64位整型\n",
    "    y_ = y_.astype(np.int64)  \n",
    "    # 返回输入特征x和标签y_           \n",
    "    return x, y_ \n",
    "\n",
    "# 调用函数，返回样本特征和样本标签\n",
    "x_train, y_train = generateds(train_path, train_txt)\n",
    "\n",
    "print('解析得到的数据：')\n",
    "print(x_train.shape)\n",
    "print(y_train.shape)\n",
    "\n",
    "# 将样本特征和样本标签保存到文件\n",
    "np.save(x_train_savepath, x_train)\n",
    "np.save(y_train_savepath, y_train)\n",
    "\n",
    "# 从文件读取样本特征和样本标签\n",
    "x_train = np.load(x_train_savepath)\n",
    "y_train = np.load(y_train_savepath)\n",
    "# print('从文件读取得到的数据：')\n",
    "print(x_train.shape)\n",
    "print(y_train.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e6044c99-0741-4378-b2b6-f60c293cc3a9",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
